package jam4j.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

public abstract class Enums {
    private Enums() { }
    
    /**
     * Return the {@link Field} object for the field defining the given enum
     * constant.
     * 
     * @param <E> The enum type of the constant.
     * @param constant The constant to reify.
     * @return The field defining the constant.
     */
    public static <E extends Enum<E>> Field fieldForConstant(E constant) {
        try {
            return constant.getDeclaringClass().getField(constant.name());
        } catch (NoSuchFieldException e) {
            // Can't happen
            throw new RuntimeException(
                    "Enum class has no field with name of enum constant (?!)",
                    e);
        }
    }
    
    /**
     * Find the given annotation on the given enum constant.
     * 
     * @param <E> The enum type of the constant.
     * @param <A> The annotation type to retrieve.
     * @param constant The constant to query.
     * @param annotationType The Class object representing {@code A}.
     * @return The annotation of the given type on the given constant, or
     * {@code null} if it has no such annotation.
     * 
     * @see #fieldForConstant(Enum)
     * @see java.lang.reflect.AnnotatedElement#getAnnotation(Class)
     */
    public static <E extends Enum<E>, A extends Annotation>
            A annotation(E constant, Class<A> annotationType) {
        return fieldForConstant(constant).getAnnotation(annotationType);
    }
}
